<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>居中元素</title>
  <style>
    .btn-x {
      margin-bottom: 10px;
    }
    #canvasBox {
      border: 1px solid #ccc;
    }
  </style>
</head>
<body>
  <div class="btn-x">
    <div>基于视窗</div>
    <button onclick="viewportCenterObjectH()">水平居中</button>
    <button onclick="viewportCenterObjectV()">垂直居中</button>
    <button onclick="viewportCenterObject()">垂直水平居中</button>
    
  </div>
  <div class="btn-x">
    <div>基于画布</div>
    <button onclick="centerObjectH()">水平居中</button>
    <button onclick="centerObjectV()">垂直居中</button>
    <button onclick="centerObject()">垂直水平居中</button>
    <button onclick="fxCenterObjectH()">动画水平居中</button>
    <button onclick="fxCenterObjectV()">动画水平垂直中</button>
    <button onclick="fxCenter()">动画水平垂直中</button>
  </div>
  <canvas id="canvasBox" width="600" height="600"></canvas>
  
<script src="../../script/fabric.js"></script>
<script>
  let canvas = null
  let rect = null

  // 使用 元素id 创建画布，此时可以在画布上框选
  canvas = new fabric.Canvas('canvasBox', {
    width: 600,
    height: 600
  })

  // 设置背景图
  fabric.Image.fromURL('../../images/bg2.jpg', img => {
    canvas.setBackgroundImage(
      img,
      canvas.renderAll.bind(canvas),
      {
        scaleX: canvas.width / img.width,
        scaleY: canvas.height / img.height
      }
    )
  })

  canvas.on('mouse:wheel', opt => {
    const delta = opt.e.deltaY // 滚轮，向上滚一下是 -100，向下滚一下是 100
    let zoom = canvas.getZoom() // 获取画布当前缩放值
    zoom *= 0.999 ** delta
    if (zoom > 20) zoom = 20
    if (zoom < 0.01) zoom = 0.01
    canvas.zoomToPoint(
      { // 关键点
        x: opt.e.offsetX,
        y: opt.e.offsetY
      },
      zoom
    )
    opt.e.preventDefault()
    opt.e.stopPropagation()
  })

  canvas.on('mouse:down', opt => { // 鼠标按下时触发
    let evt = opt.e
    canvas.isDragging = true // isDragging 是自定义的
    canvas.lastPosX = evt.clientX // lastPosX 是自定义的
    canvas.lastPosY = evt.clientY // lastPosY 是自定义的
  })

  canvas.on('mouse:move', opt => { // 鼠标移动时触发
    if (canvas.isDragging) {
      let evt = opt.e
      let vpt = canvas.viewportTransform // 聚焦视图的转换
      vpt[4] += evt.clientX - canvas.lastPosX
      vpt[5] += evt.clientY - canvas.lastPosY
      canvas.requestRenderAll()
      canvas.lastPosX = evt.clientX
      canvas.lastPosY = evt.clientY
    }
  })

  canvas.on('mouse:up', opt => { // 鼠标松开时触发
    canvas.setViewportTransform(canvas.viewportTransform) // 设置此画布实例的视口转换  
    canvas.isDragging = false
  })

  rect = new fabric.Rect({
    name: 'rect',
    top: 60, // 距离容器顶部 60px
    left: 60, // 距离容器左侧 200px
    fill: 'orange', // 填充a 橙色
    width: 60, // 宽度 60px
    height: 60, // 高度 60px
    originX: 'center',
    originY: 'center'
  })

  // 将矩形添加到画布中
  canvas.add(rect)


  // 基于视窗：水平居中
  function viewportCenterObjectH() {
    canvas.viewportCenterObjectH(rect)
    // rect.viewportCenterH()
  }

  // 基于视窗：垂直居中
  function viewportCenterObjectV() {
    canvas.viewportCenterObjectV(rect)
    // rect.viewportCenterV()
  }

  // 基于视窗：垂直水平居中
  function viewportCenterObject() {
    canvas.viewportCenterObject(rect)
    // rect.viewportCenter()
  }

  // 基于画布：动画水平居中
  function fxCenterObjectH() {
    canvas.fxCenterObjectH(rect)
  }

  // 基于画布：动画水垂直中
  function fxCenterObjectV() {
    canvas.fxCenterObjectV(rect)
  }

  // 基于画布：动画水平垂直居中
  function fxCenter() {
    canvas.fxCenterObjectH(rect)
    canvas.fxCenterObjectV(rect)
  }

  // 基于画布：水平居中
  function centerObjectH() {
    canvas.centerObjectH(rect)
    // rect.centerH()
  }

  // 基于画布：垂直居中
  function centerObjectV() {
    // canvas.centerObjectV(rect)
    rect.centerV()
  }

  // 基于画布：垂直水平居中
  function centerObject() {
    // canvas.centerObject(rect)
    rect.center()
  }
</script>
</body>
</html>